package top.songxs.yygh.hosp.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import top.songxs.yygh.common.exp.DiyException;
import top.songxs.yygh.common.utils.JwtHelper;
import top.songxs.yygh.enums.AuthStatusEnum;
import top.songxs.yygh.model.user.Patient;
import top.songxs.yygh.model.user.UserInfo;
import top.songxs.yygh.hosp.user.mapper.UserInfoMapper;
import top.songxs.yygh.hosp.user.service.PatientService;
import top.songxs.yygh.hosp.user.service.UserInfoService;
import top.songxs.yygh.vo.user.LoginVo;
import top.songxs.yygh.vo.user.UserAuthVo;
import top.songxs.yygh.vo.user.UserInfoQueryVo;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    PatientService patientService;

    @Override
    public Map<String, Object> login(LoginVo loginVo) {
        //如果微信openid是空则进行手机号登录，如果不为空去绑定手机号
        if (StringUtils.isEmpty(loginVo.getOpenid())) {
            return this.phoneLogin(loginVo);
        } else {
            return this.phoneBundle(loginVo);
        }
     /*   //从vo中获取信息
        String phone = loginVo.getPhone();
        String code = loginVo.getCode();

        //判断手机号验证码是否为空
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(code))
            throw new DiyException(20001, "数据为空");

        //判断验证码是否正确
        String s = stringRedisTemplate.opsForValue().get(phone);
        if (!code.equals(s))
            throw new DiyException(20001, "验证码错误");

        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone);
        UserInfo userInfo = baseMapper.selectOne(queryWrapper);

        if (userInfo == null) {
            //如果用户在数据库中不存在 ，则会自动注册进数据库
            userInfo = new UserInfo();
            userInfo.setPhone(phone);
            userInfo.setName("");
            userInfo.setStatus(1);
            this.save(userInfo);
        }

        if (userInfo.getStatus() == 0)
            throw new DiyException(20001, "用户已被禁用");

        Map<String, Object> map = new HashMap<>();
        String name = userInfo.getName();
        if (StringUtils.isEmpty(name))
            name = userInfo.getNickName();

        if (StringUtils.isEmpty(name))
            name = userInfo.getPhone();
        String token = JwtHelper.createToken(userInfo.getId(), name);
        map.put("name", name);
        map.put("token", token);

        return map;*/
    }

    @Override
    public void userAuth(Long userId, UserAuthVo userAuthVo) {
        UserInfo userInfo = this.getById(userId);
        String name = userAuthVo.getName();
        String certificatesType = userAuthVo.getCertificatesType();//身份类型
        String certificatesNo = userAuthVo.getCertificatesNo();//认证状态
        String certificatesUrl = userAuthVo.getCertificatesUrl();//身份存入后的url地址

        userInfo.setName(name);
        userInfo.setCertificatesType(certificatesType);
        userInfo.setCertificatesNo(certificatesNo);
        userInfo.setCertificatesUrl(certificatesUrl);
        userInfo.setAuthStatus(AuthStatusEnum.AUTH_RUN.getStatus());//已经提交了 认证中
        //进行数据更新。
        this.baseMapper.updateById(userInfo);

    }

    private Map<String, Object> phoneBundle(LoginVo loginVo) {
        //通过微信登录后绑定手机号
        String code = loginVo.getCode();
        String phone = loginVo.getPhone();
        String openid = loginVo.getOpenid();
        //校验验证码
        String codeForRedis = stringRedisTemplate.opsForValue().get(phone);
        if (!codeForRedis.equals(code)) {
            throw new DiyException(20001, "验证码校验失败");
        }
        //根据openid查询到数据中的userinfo信息
        UserInfo userInfoByOpenId = this.getByOpenid(openid);
        //根据手机号查询userinfo信息
        QueryWrapper<UserInfo> Wrapper = new QueryWrapper<>();
        Wrapper.eq("phone", phone);
        UserInfo userInfoByPhone = this.baseMapper.selectOne(Wrapper);
        //判断用户是否直接扫码登录
        if (userInfoByPhone == null) {
            //是的直接绑定手机号
            userInfoByOpenId.setPhone(phone);
            this.baseMapper.updateById(userInfoByOpenId);
        } else {
            //需要把数据库中两条数据合成一条数据
            //删除后来的，保留之前登陆的
            String isOpenId = userInfoByPhone.getOpenid();
            if (!StringUtils.isEmpty(isOpenId)) {
                //手机号已经绑定过
                throw new DiyException(20001, "手机号重复绑定");
            } else {
                //手机号没有重复绑定合并两条数据
                userInfoByPhone.setOpenid(openid);
                userInfoByPhone.setNickName(userInfoByOpenId.getNickName());
                this.baseMapper.updateById(userInfoByPhone);
                this.baseMapper.deleteById(userInfoByOpenId.getId());
            }
        }
        return this.get(userInfoByPhone);
    }

    private Map<String, Object> phoneLogin(LoginVo loginVo) {
        //通过手机号直接登录
        String phone = loginVo.getPhone();
        String code = loginVo.getCode();
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)) {
            throw new DiyException(20001, "手机号或验证码为空");
        }
        //判断验证码在redis中是否能拿到
        String codeForRedis = stringRedisTemplate.opsForValue().get(phone);
        if (StringUtils.isEmpty(codeForRedis)) {
            throw new DiyException(20001, "验证码为空");
        }
        //判断拿到验证码是否正确
        if (!codeForRedis.equals(code)) {
            throw new DiyException(20001, "验证码数据错误");
        }
        //封装查询条件
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", phone);
        //根据手机号从数据库中拿到userInfo对象
        UserInfo userInfo = this.baseMapper.selectOne(queryWrapper);
        //判断userInfo是否为空，为空是新用户注册
        if (userInfo == null) {
            userInfo = new UserInfo();
            userInfo.setAuthStatus(AuthStatusEnum.NO_AUTH.getStatus());//0  未认证状态
            userInfo.setPhone(phone);
            userInfo.setStatus(1);
            userInfo.setName("");
            int result = this.baseMapper.insert(userInfo);
            if (result < 1) {
                throw new DiyException(20001, "用户注册失败");
            }
        }
        //判断用户状态是否是禁用状态
        if (userInfo.getStatus() == 0) {
            throw new DiyException(20001, "用户状态禁用");
        }
        return this.get(userInfo);
    }

    //封装私有方法
    private Map<String, Object> get(UserInfo userInfo) {
        //返回页面显示名称
        Map<String, Object> map = new HashMap<>();
        String name = userInfo.getName();
        if (StringUtils.isEmpty(name)) {
            name = userInfo.getNickName();
        }
        if (StringUtils.isEmpty(name)) {
            name = userInfo.getPhone();
        }
        map.put("name", name);
        //根据userid和name生成token字符串
        String token = JwtHelper.createToken(userInfo.getId(), name);
        map.put("token", token);
        return map;
    }

    @Override
    public UserInfo getByOpenid(String openid) {
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("openid", openid);
        return this.baseMapper.selectOne(queryWrapper);
    }

    @Override
    public IPage<UserInfo> selectPage(Page<UserInfo> pageParam, UserInfoQueryVo vo) {
        //前端传过来的查询条件
        String name = vo.getKeyword();//关键字查询
        String createTimeEnd = vo.getCreateTimeEnd();//创建时间
        String createTimeBegin = vo.getCreateTimeBegin();//创建时间
        Integer status = vo.getStatus();//用户状态
        Integer authStatus = vo.getAuthStatus();//认证状态

        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(name))
            queryWrapper.like("name", name);

        if (!StringUtils.isEmpty(status))
            queryWrapper.eq("status", status);

        if (!StringUtils.isEmpty(authStatus))
            queryWrapper.eq("auth_status", authStatus);

        if (!StringUtils.isEmpty(createTimeBegin))
            queryWrapper.ge("create_time", createTimeBegin);  //大于等于

        if (!StringUtils.isEmpty(createTimeEnd))
            queryWrapper.le("create_time", createTimeEnd);    //小于等于


        Page<UserInfo> userInfoPage = this.baseMapper.selectPage(pageParam, queryWrapper);
        userInfoPage.getRecords().forEach(this::packageUserInfo);
        return userInfoPage;


    }

    @Override
    public void lock(Long userId, Integer status) {
        if (status == 0 || status == 1) {

            UserInfo userInfo = this.baseMapper.selectById(userId);

            if (status.equals(userInfo.getStatus())) {
                throw new DiyException(20001, "重复操作");
            }
            userInfo.setStatus(status);
            this.baseMapper.updateById(userInfo);
        }


    }

    @Override
    public Map<String, Object> show(Long userId) {

        Map<String, Object> map = new HashMap<>();
        UserInfo userInfo = this.baseMapper.selectById(userId);
        this.packageUserInfo(userInfo);
        List<Patient> patientList = patientService.findAllUserId(userId);
        map.put("userInfo",userInfo);
        map.put("patientList",patientList);

        return map;
    }

    @Override
    public void approval(Long userId, Integer authStatus) {
        if (authStatus==2|| authStatus==-1){
            UserInfo userInfo = this.baseMapper.selectById(userId);
            userInfo.setAuthStatus(authStatus);
            this.baseMapper.updateById(userInfo);
        }

    }

    //封装用户状态和认证状态
    private void packageUserInfo(UserInfo userInfo) {
        //认证状态
        userInfo.getParam().put("authStatusString", AuthStatusEnum.getStatusNameByStatus(userInfo.getAuthStatus()));
        //处理用户状态
        String statusString = userInfo.getStatus() == 0 ? "锁定" : "正常";
        userInfo.getParam().put("statusString", statusString);
    }


}
